package wsi.task.map;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.rygh.core.model.common.MapList;
import org.rygh.core.model.common.StringSet;
import org.rygh.core.xml.XmlPath;

import wsi.dataguide.tree.WSXmlLeaf;
import wsi.subgraph.tree.EntityBranch;
import wsi.task.input.InputLocation;

public class MapCandidate {

	private final List<WSXmlLeaf> sources = new ArrayList<>();
	private final Map<WSXmlLeaf, XmlPath> xPathMap = new HashMap<>();
	// private final MapList<XmlLeaf, EntityBranch> branchMap = new
	// MapList<>();
	private final MapList<String, WSXmlLeaf> leafGroupMap = new MapList<>();

	private InputLocation location;

	private MapCandidateCache cache;

	public MapCandidate(WSXmlLeaf source) {
		sources.add(source);
	}

	public void addBranch(WSXmlLeaf leaf, EntityBranch branch) {

		cache.put(cache.getStringSetKey(getSource(), leaf), branch);

		// if (branchMap.containsKey(leaf))
		// branchMap.get(leaf).add(branch);
		// else {
		// List<EntityBranch> list = new ArrayList<>();
		// list.add(branch);
		//
		// branchMap.put(leaf, list);
		// }
	}

	public void addDestNode(WSXmlLeaf leaf) {

		String key2 = leaf.getValue().getValue();

		leafGroupMap.put(key2, leaf);
	}

	public void addSource(WSXmlLeaf source) {
		sources.add(source);
	}

	public void addXPath(WSXmlLeaf leaf, XmlPath xpath) {
		xPathMap.put(leaf, xpath);

	}

	public MapCandidateCache getCache() {
		return cache;
	}

	// public Map<XmlLeaf, List<EntityBranch>> getBranchMap() {
	// return branchMap;
	// }

	public MapList<String, WSXmlLeaf> getLeafGroupMap() {
		return leafGroupMap;
	}

	public InputLocation getLocation() {
		return location;
	}

	public WSXmlLeaf getSource() {
		return sources.get(0);
	}

	public List<WSXmlLeaf> getSources() {
		return sources;
	}

	public Map<WSXmlLeaf, XmlPath> getXPathMap() {
		return xPathMap;
	}

	public boolean isSourceContentEqualTo(WSXmlLeaf x) {
		StringSet s1, s2;

		s1 = new StringSet(getSource().getValue().getValue());
		s2 = new StringSet(x.getValue().getValue());

		return s1.equals(s2);
	}

	public void setCache(MapCandidateCache cache) {
		this.cache = cache;
	}

	public void setLocation(InputLocation location) {
		this.location = location;
	}

	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder();

		for (WSXmlLeaf i : sources)
			sb.append(String.format("%s(%s)\n", i.getValue().getValue(), i
					.getValue().getName()));

		for (Entry<WSXmlLeaf, XmlPath> i : xPathMap.entrySet()) {
			sb.append(String.format("%s(%s): %s\n", i.getKey().getValue()
					.getValue(), i.getKey().getValue().getName(), i.getValue()));
		}

		return sb.toString();
	}

	public String toTripleString(WSXmlLeaf n) {
		// assert branchMap.containsKey(n);
		StringSet ss = cache.getStringSetKey(getSource(), n);

		// List<EntityBranch> branches = branchMap.get(n);
		assert cache.contains(ss) : ss + "\n" + cache.getCacheMap().keySet();
		List<EntityBranch> branches = cache.get(ss);

		StringBuilder sb = new StringBuilder();

		for (EntityBranch i : branches)
			sb.append(String.format("%s<br>", i.toString("<br>")));

		return sb.toString();
	}
}
